package com.example.shuimu;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest;
import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse;
import com.serotonin.modbus4j.msg.ReadInputRegistersRequest;
import com.serotonin.modbus4j.msg.ReadInputRegistersResponse;
import com.serotonin.modbus4j.msg.WriteMaskRegisterRequest;
import com.serotonin.modbus4j.msg.WriteRegisterRequest;
import com.serotonin.modbus4j.serial.SerialPortWrapper;

import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    SerialPortWrapper serialParameters ;
    ModbusFactory modbusFactory ;
    ModbusMaster master ;
    ProgressBar pb ;
    private TextView moshi;  //
    private TextView shuifa;  //
    private TextView kaiguang;  //
    private TextView tv_shuiwei;  //
    private TextView tv_shoudong;  //
    private TextView tv_air;  //

    private Button kongzhizidong1;  //
    private Button kongzhizidong2;  //


    private Button famen1;  //
    private Button famen2;  //

    private Button shuibeng1;  //
    private Button shuibeng2;  //
    private Button btn_qiehuan3;  //

    private Button btn_sheweishoudong;  //
    private Button btn_sheweizidong;  //

    Timer timer = new Timer();
    TimerTask task;
    short dianjishort = 0;   // 电机状态
    short famenshort = 0;    //阀门状态
    short kongzhimoshishort = 0; //控制模式
    short yewei = 0; //液位

    String url = "tcp://broker.emqx.io:1883";
    String user = "1553592282";
    String pass = "1553592282";
    String id = "mqttx_f0621e13";


    boolean shengaoflag = false;
    private ScheduledExecutorService scheduler;
    private MqttClient client;
    private Handler handler;
    //这些都写你自己的或者找个测试的地址
    private String host = "tcp://broker.emqx.io:1883";     // TCP协议
    private String userName = "1553592282"; //mqtt用户名称
    private String passWord = "1553592282";//mqtt用户密码
    private String mqtt_id = "mqttx_f0621e13A";//mqtt id
    private String mqtt_sub_topic = "set_penlin_status_gd1";//mqtt订阅的主题的标识
    private String mqtt_pub_topic = "get_penlin_status_gd1";//mqtt你发布的主题的标识
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static MqttConnectOptions mMqttConnectOptions;
    MqttAndroidClient mqttAndroidClient = null;
    private int wendu,zaoseng,p25,p10,qiya;
    private float shidu,fengsu;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        getSupportActionBar().hide();
        //全屏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        pb = findViewById(R.id.battery_pb);

        moshi = findViewById(R.id.tv_moshi);
        shuifa = findViewById(R.id.tv_famen);
        kaiguang = findViewById(R.id.tv_shuibeng);
        tv_shuiwei = findViewById(R.id.tv_shuiwei);


        kongzhizidong1 = findViewById(R.id.btn_qiehuan1);
        kongzhizidong2 = findViewById(R.id.btn_qiehuan2);
        btn_qiehuan3 = findViewById(R.id.btn_qiehuan3);
        famen1 = findViewById(R.id.btn_send1);
        famen2 = findViewById(R.id.btn_send2);
        shuibeng1 = findViewById(R.id.btn_shuibeng1);
        shuibeng2 = findViewById(R.id.btn_shuibeng2);
        btn_qiehuan3 = findViewById(R.id.btn_qiehuan3);
        tv_air = findViewById(R.id.tv_air);


        btn_sheweishoudong = findViewById(R.id.btn_shoudong);
        btn_sheweizidong = findViewById(R.id.btn_zidong);

        kongzhizidong1.setOnClickListener(this);
        kongzhizidong2.setOnClickListener(this);
        famen1.setOnClickListener(this);
        famen2.setOnClickListener(this);
        shuibeng1.setOnClickListener(this);

        shuibeng2.setOnClickListener(this);
        btn_qiehuan3.setOnClickListener(this);

        btn_sheweishoudong.setOnClickListener(this);
        btn_sheweizidong.setOnClickListener(this);

        initSirPort();

        task = new TimerTask() {
            @Override
            public void run() {
                // 执行某个任务
                GetInfo();

                SendAir();
            }
        };

        timer.schedule(task, 1000, 3000);

        init();
    }

    //发送空气参数
    private void SendAir() {
        Random random = new Random();
        wendu = random.nextInt(28 - 27 + 1) + 27;
        shidu =  (float) (33 +0.1 * (random.nextInt(4 - 1 + 1) + 1));
        zaoseng = 46;

        if(shengaoflag){

            p25 = 400;
            p10 =400;
        }else {
            p25 = 36;
            p10 =122;

        }

        qiya = 1001;
        fengsu = 0.8f;
        runOnUiThread(new Runnable(){

            @Override
            public void run() {
                tv_air.setText("空气参数："+"温度:"+wendu+"，湿度:"+shidu+"，噪声:"+zaoseng+"，PM2.5:"+p25+"，PM10:"+p10+"，气压:"+qiya+"，风速:"+fengsu);

                sendMqtt(mqtt_pub_topic,"air="+wendu+","+shidu+","+zaoseng+","+p25+","+p10+","+qiya+","+fengsu+","+dateFormat.format(new Date()));
            }

        });


        //显示到界面

        //发送到MQTT


    }

    private String TAG = "mqtt";
    /**
     * 初始化
     */
    private void init() {
        try {
            //host为主机名，test为clientid即连接MQTT的客户端ID，一般以客户端唯一标识符表示，MemoryPersistence设置clientid的保存形式，默认为以内存保存
            client = new MqttClient(host, mqtt_id,
                    new MemoryPersistence());
            //MQTT的连接设置
            MqttConnectOptions options = new MqttConnectOptions();
            //设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录，这里设置为true表示每次连接到服务器都以新的身份连接
            options.setCleanSession(false);
            //设置连接的用户名
            options.setUserName(userName);
            //设置连接的密码
            options.setPassword(passWord.toCharArray());
            // 设置超时时间 单位为秒
            options.setConnectionTimeout(10);
            // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线，但这个方法并没有重连的机制
            options.setKeepAliveInterval(20);
            startReconnect(options);

            //设置回调
            client.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable cause) {
                    //连接丢失后，一般在这里面进行重连
                    Log.e(TAG, "连接丢失后connectionLost----------");
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    //publish后会执行到这里
                    Log.d(TAG, "publish后会执行到这里deliveryComplete---------"
                            + token.isComplete());
                }

                @Override
                public void messageArrived(String topicName, MqttMessage message)
                        throws Exception {
                    //subscribe后得到的消息会执行到这里面
                    Log.d(TAG, "subscribe后得到的消息会执行到这里面messageArrived----------" + message);
                    if(message.toString().equals("shuibeng=1")){

                        zidong1();
                    }
                    if(message.toString().equals("shuibeng=0")){

                        zidong3();
                    }
                    if(message.toString().equals("famen=1")){
                        famen1();

                    }if(message.toString().equals("famen=0")){

                        famen2();
                    }

                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }


        new Thread(){
            @Override
            public void run() {
                super.run();
                try {
                    Thread.sleep(2000);
                    client.subscribe("set_penlin_status");
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }.start();



    }

    // MQTT重新连接函数
    private void startReconnect(MqttConnectOptions options) {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                if (!client.isConnected()) {
                    mqttConnect(options);
                }
            }
        }, 0 * 1000, 10 * 1000, TimeUnit.MILLISECONDS);
    }
    // 订阅函数    (下发任务/命令)
    public void publishmessageplus(String topic, String message2) {
        if (client == null || !client.isConnected()) {
            return;
        }
        MqttMessage message = new MqttMessage();
        message.setPayload(message2.getBytes());
        try {
            client.publish(topic, message);
        } catch (MqttException e) {

            e.printStackTrace();
        }
    }
    // MQTT连接函数
    private void mqttConnect(MqttConnectOptions options) {
        new Thread(() -> {
            try {
                if (!(client.isConnected()))  //如果还未连接
                {
                    client.connect(options);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
    }




    private void GetInfo(){



        try {


            ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(1, 1102, 1);
            ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse)master.send(request );
            if (response.isException()) {
                Log.e("SirPort1", "Exception response:" + response.getExceptionMessage());
            } else {
                short[] list = response.getShortData();
                dianjishort = list[0];

                Log.e("MOD", "电机状态1004"+dianjishort);
            }
        }catch (Exception e){

            Log.e("SirPort3", e.getMessage());
        }
        try {

            ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(1, 1103, 1);
            ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse)master.send(request );
            if (response.isException()) {
                Log.e("SirPort1", "Exception response:" + response.getExceptionMessage());
            } else {
                short[] list = response.getShortData();
                famenshort = list[0];

                Log.e("MOD", "阀门状态1006"+dianjishort);
            }
        }catch (Exception e){
            Log.e("SirPort3", e.getMessage());
        }
        try {
            //Integer addr = Integer.parseInt("40001", 16);
            // 电机状态 1004
            ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(1, 1105, 1);
            ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse)master.send(request );
            if (response.isException()) {
                Log.e("SirPort1", "Exception response:" + response.getExceptionMessage());
            } else {
                short[] list = response.getShortData();
                kongzhimoshishort = list[0];

                Log.e("MOD", "控制模式1010"+dianjishort);
            }
        }catch (Exception e){
            Log.e("SirPort3", e.getMessage());
        }
        try {
            //Integer addr = Integer.parseInt("40001", 16);
            // 液位 1008
            ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(1, 1104, 1);
            ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse)master.send(request );
            if (response.isException()) {
                Log.e("SirPort1", "Exception response:" + response.getExceptionMessage());
            } else {
                short[] list = response.getShortData();
                yewei = list[0];

                Log.e("MOD", "液位1008"+yewei);
            }
        }catch (Exception e){
            Log.e("SirPort3", e.getMessage());
        }

//        shuibeng=0  /  1
//        famen=0 / 1

        if(famenshort == 0){

            sendMqtt(mqtt_sub_topic,"famen=0");
        }else {
            sendMqtt(mqtt_sub_topic,"famen=1");

        }

        if(dianjishort == 0){
            sendMqtt(mqtt_sub_topic,"shuibeng=0");

        }else {
            sendMqtt(mqtt_sub_topic,"shuibeng=1");

        }





        runOnUiThread(new Runnable(){

            @Override
            public void run() {
                if( dianjishort == 0 ){

                    kaiguang.setText("喷淋水泵：关闭");
                }else {
                    kaiguang.setText("喷淋水泵：开启");

                }
                if( famenshort == 0 ){

                    shuifa.setText("进水阀门：关闭");
                }else {
                    shuifa.setText("进水阀门：开启");

                }
                if( kongzhimoshishort  == 0 ){
                    moshi.setText("控制模式：停止");

                }else if(kongzhimoshishort  == 1){

                    moshi.setText("控制模式：手动");
                }else  if(kongzhimoshishort  == 2){
                    moshi.setText("控制模式：开启");
                }


                pb.setProgress(yewei);
                tv_shuiwei.setText(yewei+"mm");

            }

        });


        //写入数据

        try {

            master.send(new WriteRegisterRequest(1,1110,1000));  //泵开液位设定值
            master.send(new WriteRegisterRequest(1,1111,500));  //泵关液位设定值
            master.send(new WriteRegisterRequest(1,1112,600));  //阀开液位设定值
            master.send(new WriteRegisterRequest(1,1113,1200));  //阀关液位设定值

        }catch (Exception e){

            Log.e("SirPort3", e.getMessage());
        }



    }

    private void initSirPort() {
        serialParameters = new SerialPortWrapperImpl("/dev/ttyS4", 9600, 8, 1, 0);
        modbusFactory = new ModbusFactory();
        master = modbusFactory.createRtuMaster(serialParameters);

        try {
            master.setTimeout(3000);
            master.setRetries(3);
            master.init();

            Log.e("SirPort", " master.init()" );




        }catch (ModbusInitException  e) {


            e.printStackTrace();
        }finally {
            //master.destroy();
        }

    }
    // CDAB: 保持字节顺序不变
    public static float[] convertCDAB(byte[] bytes) {
        if (bytes.length % 4 != 0) {
            throw new IllegalArgumentException("The length of the byte array must be divisible by 4.");
        }

        ByteBuffer buffer = ByteBuffer.wrap(bytes);
        float[] floats = new float[bytes.length / 4];
        for (int i = 0; i < floats.length; i++) {
            floats[i] = buffer.getFloat();
        }
        return floats;
    }
    @Override
    public void onClick(View view) {
        switch (view.getId()){

            case R.id.btn_qiehuan1:
                zidong1();
                break;
            case R.id.btn_qiehuan2:
                zidong2();
                break;
                case R.id.btn_qiehuan3:
                zidong3();
                break;

            case R.id.btn_send1:
                famen1();
                break;
            case R.id.btn_send2:
                famen2();
                break;

            case R.id.btn_shuibeng1:
                shuibeng1();
                break;
            case R.id.btn_shuibeng2:
                shuibeng2();
                break;
//            btn_sheweishoudong = findViewById(R.id.btn_shoudong);
//            btn_sheweizidong = findViewById(R.id.btn_zidong);

            case R.id.btn_shoudong:
                sheweishoudong(); //设为手动
                break;
            case R.id.btn_zidong:   //设为自动
                sheweizidong();

        }
    }
    //设为自动  然后关闭 喷淋设备
    private void sheweizidong() {
        new Thread(){
            @Override
            public void run() {
                try {
                    Log.e("MingLing","设为自动  然后关闭 喷淋设备");
                    master.send(new WriteRegisterRequest(1,1107,0));  // 自动模式，关机
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,0));  // 自动模式，关机
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,0));  // 自动模式，关机
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,0));  // 自动模式，关机

                }catch (Exception e){
                    Log.e("Exception", e.getMessage());
                }
                super.run();

            }
        }.start();
    }
    //设为手动
    private void sheweishoudong() {
        new Thread(){
            @Override
            public void run() {
                try {
                    Log.e("MingLing","手动模式");
                    master.send(new WriteRegisterRequest(1,1107,1));  // 手动模式
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,1));  // 手动模式
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,1));  // 手动模式
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,1));  // 手动模式
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,1));  // 手动模式


                }catch (Exception e){
                    Log.e("Exception", e.getMessage());
                }

                super.run();

            }
        }.start();
    }


    private void shuibeng2() {   // 水泵关闭
//        try {
//            master.send(new WriteRegisterRequest(1,1108,0));  //
//        }catch (Exception e){
//
//            Log.e("Exception", e.getMessage());
//        }
        new Thread(){
            @Override
            public void run() {
                try {
                    Log.e("MingLing","水泵关闭");
                    master.send(new WriteRegisterRequest(1,1108,0));  //
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1108,0));  //
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1108,0));  //
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1108,0));  //


                }catch (Exception e){
                    Log.e("Exception", e.getMessage());
                }
                super.run();

            }
        }.start();
    }
        //    水泵开启
    private void shuibeng1() {
//        try {
//            master.send(new WriteRegisterRequest(1,1108,1));  //
//        }catch (Exception e){
//
//            Log.e("Exception", e.getMessage());
//        }


        new Thread(){
            @Override
            public void run() {
                try {
                    Log.e("MingLing","水泵开启");
                    master.send(new WriteRegisterRequest(1,1108,1));  //
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1108,1));  //
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1108,1));  //
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1108,1));  //


                }catch (Exception e){
                    Log.e("Exception", e.getMessage());
                }
                super.run();

            }
        }.start();

    }
//    阀门关闭
    private void famen2() {
//        try {
//            master.send(new WriteRegisterRequest(1,1109,0));  //
//        }catch (Exception e){
//
//            Log.e("Exception", e.getMessage());
//        }

        new Thread(){
            @Override
            public void run() {
                try {
                    Log.e("MingLing","阀门关闭");
                    master.send(new WriteRegisterRequest(1,1109,0));  //
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1109,0));  //
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1109,0));  //
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1109,0));  //

                }catch (Exception e){
                    Log.e("Exception", e.getMessage());
                }
                super.run();

            }
        }.start();
    }
    //阀门开启
    private void famen1() {
//        try {
//            master.send(new WriteRegisterRequest(1,1109,1));  //
//        }catch (Exception e){
//
//            Log.e("Exception", e.getMessage());
//        }

        new Thread(){
            @Override
            public void run() {
                try {
                    Log.e("MingLing","开阀门");
                    master.send(new WriteRegisterRequest(1,1109,1));  //
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1109,1));  //
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1109,1));  //
                     Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1109,1));  //


                }catch (Exception e){
                    Log.e("Exception", e.getMessage());
                }
                super.run();

            }
        }.start();
    }






    private void zidong2() {
        try {

            master.send(new WriteRegisterRequest(1,1107,1));  // 手动模式
            Log.e("MingLing","手动模式");
        }catch (Exception e){
            Log.e("Exception", e.getMessage());
        }
    }
    //  自动开机
    private void zidong1() {
//        try {
//
//            master.send(new WriteRegisterRequest(1,1107,2));  //  命令式  开机
//        }catch (Exception e){
//            Log.e("Exception", e.getMessage());
//        }

        new Thread(){
            @Override
            public void run() {
                try {
                    Log.e("MingLing","命令式  开机");
                    master.send(new WriteRegisterRequest(1,1107,2));  //  命令式  开机
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,2));  //  命令式  开机
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,2));  //  命令式  开机
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,2));  //  命令式  开机
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,2));  //  命令式  开机


                }catch (Exception e){
                    Log.e("Exception", e.getMessage());
                }
                super.run();

            }
        }.start();
    }
    //  自动关机
    private void zidong3() {
//        try {
//
//            master.send(new WriteRegisterRequest(1,1107,0));  // 命令式  关机
//        }catch (Exception e){
//            Log.e("Exception", e.getMessage());
//        }

        new Thread(){
            @Override
            public void run() {
                try {
                    Log.e("MingLing"," 命令式  关机");
                    master.send(new WriteRegisterRequest(1,1107,0));  // 命令式  关机
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,0));  // 命令式  关机
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,0));  // 命令式  关机
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,0));  // 命令式  关机
                    Thread.sleep(100);
                    master.send(new WriteRegisterRequest(1,1107,0));  // 命令式  关机


                }catch (Exception e){
                    Log.e("Exception", e.getMessage());
                }
                super.run();

            }
        }.start();
    }

    public void shengao(View view) {

    }

    public void jiangdi(View view) {

    }

    private void sendMqtt(String topic,String meg){
        if(client !=null && client.isConnected()){

            MqttMessage message = new MqttMessage();
            message.setPayload(meg.getBytes());
            try {
                client.publish(topic,message);
            } catch (MqttException e) {
                e.printStackTrace();
            }

        }

    }
}